#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */

#include "RTI_HAL_KA.h"
#include "Services_KA.h"
#include "MC34671_Handler.h"
#include "BUCK_Handler.h"
#include "LED_Handler.h"

extern uint8 u8isetStatus, u8BuckStatus;
extern stateMachine sChargerState;

void main(void) 
{
    uint16 u16delay;
    uint8 u8batterycounter = 0;

    EnableInterrupts; /* enable interrupts */
    /* include your code here */
    
    __RESET_WATCHDOG();

    vfnSystemOptionsInit(); // Enable watchdog, short period, default pinout
    
    vfnICS_Configure(); // Internal clock source, 10 MHZ, bus divider = 1
    
    vfnMC34671_StateInit(); // Initialize charger state machine
    
    vfnBuck_PWM_Init();
    
    vfnBuck_ADC_Init();
    
    vfnGPIO_Init();  
    
    vfnRTI_Init();
    
    vfnLED_Init();
    
    u8isetStatus = ISET_250MA;
                  
    for(;;) 
    {
        /*
        asm
        {
            WAIT;
        }
        */
        while(!u8RTI_CheckFlag());
        
        if (u8CheckPendingInterrupts() && PENDING_INTERRUPT_RTI)    // if MCU was woken by RTI, 
                                                                    // things are working OK
        {
            vfnRTI_ClearFlag(); // clear flag   
        }   
        else
        {
            continue;
        }
        __RESET_WATCHDOG(); /* feeds the dog */

        vfnLED_Management();        
       
        // Check the Charger State machine's current state and act accordingly
        
        if (sChargerState.u8currentState & WAIT_FOR_BATTERY)
        {
            if (u8MC34671_IsBatteryPresent())
            {
            	u8batterycounter++;
            	
            	if (u8batterycounter == 50)
            	{
	                vfnMC34671_UpdateStateMachine();
	                sChargerState.u8currentState = WAIT_FOR_BUCK;
	                vfnBuck_TurnOn();
	                u8batterycounter = 0;
            	}
            }
            else
            {
            	u8batterycounter = 0;
            }
        }
          
        else if (sChargerState.u8currentState & WAIT_FOR_BUCK)
        {
            if (!u8Buck_IsOutputLow()) // If buck output voltage is high enough
            {

                vfnMC34671_UpdateStateMachine();
                sChargerState.u8currentState = TRICKLE_CHARGE;
                MC34671_EN = MC34671_ENABLE;
                
                u16delay = 0x03FF;
	            while(u16delay--);
                
                while (u8Buck_IsOutputLow())
	            {
	            	vfnBuck_RegulateVoltage();
	            	__RESET_WATCHDOG();
	            	u16delay = 0x03FF;
	            	while(u16delay--);
	            }
                
            }
            vfnBuck_RegulateVoltage();
            
        }
        
        else if (sChargerState.u8currentState & TRICKLE_CHARGE)
        {
            if (!MC34671_FAST)   // If the FAST pin is active low
            {
                // Update the state machine and call the buck maintenance
                // function, change to CONSTANT_CURRENT state.
                
                vfnMC34671_UpdateStateMachine();
                sChargerState.u8currentState = CONSTANT_CURRENT;
                vfnBuck_RegulateVoltage();           
            }
            else    // If not then we check to see if there is still a battery
            {       // being charged
                if(!MC34671_CHG)   // If the CHG pin is active low
                {
                    vfnBuck_RegulateVoltage();   
                }
                else    // if not, then battery was disconnected
                {	
                    vfnMC34671_UpdateStateMachine();
                    MC34671_EN = MC34671_DISABLE;
                    vfnBuck_TurnOff();
                    sChargerState.u8currentState = WAIT_FOR_BATTERY;
                }
            }
        }
        
        else if (sChargerState.u8currentState & CONSTANT_CURRENT)
        {
        	//POWER_LED = 0;
        	//CHARGING_LED = 1;
            if (!u8MC34671_IsIbatConstant())
            {
                vfnMC34671_UpdateStateMachine();
                sChargerState.u8currentState = CONSTANT_VOLTAGE;        
            }
            vfnBuck_RegulateVoltage();
        }
          
        else if (sChargerState.u8currentState & CONSTANT_VOLTAGE)
        {
        	//CHARGING_LED = 0;
        	//POWER_LED = 1;
            if (u8MC34671_IsIbatUnderEOC())
            {
                MC34671_EN = MC34671_DISABLE;
                vfnBuck_TurnOff();
                vfnMC34671_UpdateStateMachine();
                sChargerState.u8currentState = WAIT_FOR_BATTERY;        
            }
            vfnBuck_RegulateVoltage();
        }       
        
        else if (sChargerState.u8currentState & WAIT_FOR_SUN1)
        {
            vfnMC34671_StorePanelVoltage(); 
            vfnMC34671_UpdateStateMachine();
            sChargerState.u8currentState = WAIT_FOR_SUN2;   
        }
        
        else if (sChargerState.u8currentState & WAIT_FOR_SUN2)
        {
            if (u8MC34671_IsPanelVoltageOK())
            {
                vfnMC34671_UpdateStateMachine();
                vfnBuck_TurnOn();
                sChargerState.u8currentState = WAIT_FOR_BUCK;        
            }
        }
         
        else
        {
            for(;;);   // If the state machine is no known state, then
                        // initiate an infinite loop to trigger a watchdog RST
        }
          
        
    } /* loop forever */
      /* please make sure that you never leave main */
}
